// FeedStory.cs
// Facebook/Framework/Service
// Copyright (c) 2007, Nikhil Kothari. All Rights Reserved.
//

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;

namespace Facebook.Service {

    /// <summary>
    /// Represents a story that can be published to the news feed or mini-feed.
    /// </summary>
    public sealed class FeedStory {

        private string _title;
        private string _body;
        private List<FeedImage> _images;

        private FeedStoryTemplate _template;
        private string _userID;
        private ICollection<string> _targetUserIDs;
        private Hashtable _titleTemplateValues;
        private Hashtable _bodyTemplateValues;

        /// <summary>
        /// Initializes a feed story with the specified title.
        /// </summary>
        /// <param name="title">The title of the story</param>
        public FeedStory(string title) {
            if (String.IsNullOrEmpty(title)) {
                throw new ArgumentNullException("title");
            }

            _title = title;
        }

        /// <summary>
        /// Initializes a feed story with the specified story template for the
        /// specified user.
        /// </summary>
        /// <param name="template">The template of the story.</param>
        /// <param name="userID">The primary user or actor.</param>
        public FeedStory(FeedStoryTemplate template, string userID)
            : this(template, userID, null) {
        }

        /// <summary>
        /// Initializes a feed story with the specified story template, and
        /// the specified user and target users.
        /// </summary>
        /// <param name="template">The template of the story.</param>
        /// <param name="userID">The primary user or actor.</param>
        /// <param name="targetUserIDs">The list of target users involved in the story.</param>
        public FeedStory(FeedStoryTemplate template, string userID, ICollection<string> targetUserIDs) {
            if (template == null) {
                throw new ArgumentNullException("template");
            }
            if (String.IsNullOrEmpty(userID)) {
                throw new ArgumentNullException("userID");
            }

            _template = template;
            _userID = userID;
            _targetUserIDs = targetUserIDs;
        }

        internal string Body {
            get {
                return _body;
            }
        }

        internal Hashtable BodyTemplateValues {
            get {
                return _bodyTemplateValues;
            }
        }

        internal ICollection<FeedImage> Images {
            get {
                return _images;
            }
        }

        internal bool IsTemplated {
            get {
                return (_template != null);
            }
        }

        internal ICollection<string> TargetUserIDs {
            get {
                return _targetUserIDs;
            }
        }

        internal FeedStoryTemplate Template {
            get {
                return _template;
            }
        }

        internal string Title {
            get {
                return _title;
            }
        }

        internal Hashtable TitleTemplateValues {
            get {
                return _titleTemplateValues;
            }
        }

        internal string UserID {
            get {
                return _userID;
            }
        }

        /// <summary>
        /// Adds the specified body to the story as its content. The body is represented
        /// as FBML markup.
        /// If this story instance is created from a template, the body represents
        /// the custom content associated with this instance, distinct from the shared
        /// template.
        /// </summary>
        /// <param name="body"></param>
        public void AddBody(string body) {
            _body = body;
        }

        /// <summary>
        /// Adds the specified image to the story. A maximum of 4 images can be added.
        /// </summary>
        /// <param name="image">The image to be added.</param>
        public void AddImage(FeedImage image) {
            if (_images == null) {
                _images = new List<FeedImage>();
            }
            else if (_images.Count == 4) {
                throw new InvalidOperationException("A maximum of 4 images can be added.");
            }

            _images.Add(image);
        }

        /// <summary>
        /// Adds a value to replace the specified named placeholder in the template definition.
        /// This looks for named placeholders in both the title and body templates.
        /// </summary>
        /// <param name="name">The name of the placeholder to be replaced.</param>
        /// <param name="value">The value to use to fill the placeholder.</param>
        public void AddTemplateValue(string name, string value) {
            if (IsTemplated == false) {
                throw new InvalidOperationException("Template values can only be added to templated stories.");
            }
            if (String.IsNullOrEmpty(name)) {
                throw new ArgumentNullException("name");
            }
            if (String.IsNullOrEmpty(value)) {
                throw new ArgumentNullException("value");
            }

            string templateName = "{" + name + "}";
            if (_template.TitleTemplate.IndexOf(templateName, StringComparison.Ordinal) >= 0) {
                if (_titleTemplateValues == null) {
                    _titleTemplateValues = new Hashtable();
                }
                _titleTemplateValues[name] = value;
            }

            if ((String.IsNullOrEmpty(_template.BodyTemplate) == false) &&
                (_template.BodyTemplate.IndexOf(templateName, StringComparison.Ordinal) >= 0)) {
                if (_bodyTemplateValues == null) {
                    _bodyTemplateValues = new Hashtable();
                }
                _bodyTemplateValues[name] = value;
            }
        }
    }
}
